using System.Text;
using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using Csla.Validation;
using BA.DAL;
using BA;

namespace BlazeApps.Library.Events
{ 
	[Serializable()] 
	public class EventDetail : Csla.BusinessBase<EventDetail>
	{
        private BlazeApps.Library.ConfigSettings Config = new BlazeApps.Library.ConfigSettings();
        private BA.DAL.DBUtility DAL = new BA.DAL.DBUtility();
        private Procedures Procs = new Procedures();

		#region Business Properties and Methods

		//declare members
        private Guid _eventID = Guid.NewGuid();
        private string _eventTitle = string.Empty;
        private string _eventDetails = string.Empty;
        private SmartDate _eventDate = new SmartDate(DateTime.Now);
        private Guid _userID = Guid.Empty;
        private SmartDate _startDate = new SmartDate(true);
        private SmartDate _endDate = new SmartDate(false);
        private int _day = 0;
        private int _month = 0;
        private int _year = 0;
        private int _hr = 0;
        private int _min = 0;
        private string _meridian = string.Empty;
        private Guid _occurenceid = Guid.Empty;
        private bool _private = false;
        private bool _updateoccurence = false;
        private bool _deleteoccurence = false;

		[System.ComponentModel.DataObjectField(true, false)]
        public Guid EventID
        {
            get
            {
                CanReadProperty("EventID", true);
                return _eventID;
            }
        }

        public string EventTitle
        {
            get
            {
                CanReadProperty("EventTitle", true);
                return _eventTitle;
            }
            set
            {
                CanWriteProperty("EventTitle", true);
                if (value == null)
                    value = string.Empty;
                if (!_eventTitle.Equals(value))
                {
                    _eventTitle = value;
                    PropertyHasChanged("EventTitle");
                }
            }
        }

        public string EventDetails
        {
            get
            {
                CanReadProperty("EventDetails", true);
                return _eventDetails;
            }
            set
            {
                CanWriteProperty("EventDetails", true);
                if (value == null)
                    value = string.Empty;
                if (!_eventDetails.Equals(value))
                {
                    _eventDetails = value;
                    PropertyHasChanged("EventDetails");
                }
            }
        }

        public DateTime EventDate
        {
            get
            {
                CanReadProperty("EventDate", true);
                return _eventDate.Date;
            }
        }

        public string EventDateString
        {
            get
            {
                CanReadProperty("EventDateString", true);
                return _eventDate.Text;
            }
            set
            {
                CanWriteProperty("EventDateString", true);
                if (value == null)
                    value = string.Empty;
                if (!_eventDate.Equals(value))
                {
                    _eventDate.Text = value;
                    PropertyHasChanged("EventDateString");
                }
            }
        }

        public Guid UserID
        {
            get
            {
                CanReadProperty("UserID", true);
                return _userID;
            }
            set
            {
                CanWriteProperty("UserID", true);
                if (!_userID.Equals(value))
                {
                    _userID = value;
                    PropertyHasChanged("UserID");
                }
            }
        }

        public DateTime StartDate
        {
            get
            {
                CanReadProperty("StartDate", true);
                return _startDate.Date;
            }
        }

        public string StartDateString
        {
            get
            {
                CanReadProperty("StartDateString", true);
                return _startDate.Text;
            }
            set
            {
                CanWriteProperty("StartDateString", true);
                if (value == null)
                    value = string.Empty;
                if (!_startDate.Equals(value))
                {
                    _startDate.Text = value;
                    PropertyHasChanged("StartDateString");
                }
            }
        }

        public DateTime EndDate
        {
            get
            {
                CanReadProperty("EndDate", true);
                return _endDate.Date;
            }
        }

        public string EndDateString
        {
            get
            {
                CanReadProperty("EndDateString", true);
                return _endDate.Text;
            }
            set
            {
                CanWriteProperty("EndDateString", true);
                if (value == null)
                    value = string.Empty;
                if (!_endDate.Equals(value))
                {
                    _endDate.Text = value;
                    PropertyHasChanged("EndDateString");
                }
            }
        }

        public int Day
        {
            get
            {
                CanReadProperty("Day", true);
                return _day;
            }
            set
            {
                CanWriteProperty("Day", true);
                if (!_day.Equals(value))
                {
                    _day = value;
                    PropertyHasChanged("Day");
                }
            }
        }

        public int Month
        {
            get
            {
                CanReadProperty("Month", true);
                return _month;
            }
            set
            {
                CanWriteProperty("Month", true);
                if (!_month.Equals(value))
                {
                    _month = value;
                    PropertyHasChanged("Month");
                }
            }
        }

        public int Year
        {
            get
            {
                CanReadProperty("Year", true);
                return _year;
            }
            set
            {
                CanWriteProperty("Year", true);
                if (!_year.Equals(value))
                {
                    _year = value;
                    PropertyHasChanged("Year");
                }
            }
        }

        public int Hr
        {
            get
            {
                CanReadProperty("Hr", true);
                return _hr;
            }
            set
            {
                CanWriteProperty("Hr", true);
                if (!_hr.Equals(value))
                {
                    _hr = value;
                    PropertyHasChanged("Hr");
                }
            }
        }

        public int Min
        {
            get
            {
                CanReadProperty("Min", true);
                return _min;
            }
            set
            {
                CanWriteProperty("Min", true);
                if (!_min.Equals(value))
                {
                    _min = value;
                    PropertyHasChanged("Min");
                }
            }
        }

        public string Meridian
        {
            get
            {
                CanReadProperty("Meridian", true);
                return _meridian;
            }
            set
            {
                CanWriteProperty("Meridian", true);
                if (value == null)
                    value = string.Empty;
                if (!_meridian.Equals(value))
                {
                    _meridian = value;
                    PropertyHasChanged("Meridian");
                }
            }
        }

        public Guid Occurenceid
        {
            get
            {
                CanReadProperty("Occurenceid", true);
                return _occurenceid;
            }
            set
            {
                CanWriteProperty("Occurenceid", true);
                if (!_occurenceid.Equals(value))
                {
                    _occurenceid = value;
                    PropertyHasChanged("Occurenceid");
                }
            }
        }

        public bool Private
        {
            get
            {
                CanReadProperty("Private", true);
                return _private;
            }
            set
            {
                CanWriteProperty("Private", true);
                if (!_private.Equals(value))
                {
                    _private = value;
                    PropertyHasChanged("Private");
                }
            }
        }

        public bool UpdateOccurence
        {
            get
            {
                CanReadProperty("UpdateOccurence", true);
                return _updateoccurence;
            }
            set
            {
                CanWriteProperty("UpdateOccurence", true);
                if (!_updateoccurence.Equals(value))
                {
                    _updateoccurence = value;
                    PropertyHasChanged("UpdateOccurence");
                }
            }
        }

        public bool DeleteOccurence
        {
            get
            {
                CanReadProperty("DeleteOccurence", true);
                return _deleteoccurence;
            }
            set
            {
                CanWriteProperty("DeleteOccurence", true);
                if (!_deleteoccurence.Equals(value))
                {
                    _deleteoccurence = value;
                    PropertyHasChanged("DeleteOccurence");
                }
            }
        }
 
		protected override object GetIdValue()
		{
			return _eventID;
		}

		#endregion //Business Properties and Methods

		#region Validation Rules
		private void AddCustomRules()
		{
			//add custom/non-generated rules here...
		}

		private void AddCommonRules()
		{
			//
			// EventTitle
			//
			ValidationRules.AddRule(CommonRules.StringRequired, "EventTitle");
			//
			// EventDetails
			//
			ValidationRules.AddRule(CommonRules.StringRequired, "EventDetails");
			//
			// EventDate
			//
			ValidationRules.AddRule(CommonRules.StringRequired, "EventDateString");
		}

		protected override void AddBusinessRules()
		{
			AddCommonRules();
			AddCustomRules();
		}
		#endregion //Validation Rules

		#region Authorization Rules
		protected override void AddAuthorizationRules()
		{
			//TODO: Define authorization rules in EventDetail
			//AuthorizationRules.AllowRead("EventID", "EventDetailReadGroup");
			//AuthorizationRules.AllowRead("EventTitle", "EventDetailReadGroup");
			//AuthorizationRules.AllowRead("EventDetails", "EventDetailReadGroup");
			//AuthorizationRules.AllowRead("EventDate", "EventDetailReadGroup");
			//AuthorizationRules.AllowRead("EventDateString", "EventDetailReadGroup");
			//AuthorizationRules.AllowRead("UserID", "EventDetailReadGroup");
			//AuthorizationRules.AllowRead("AllowSubscriptions", "EventDetailReadGroup");
			//AuthorizationRules.AllowRead("AllowComments", "EventDetailReadGroup");

			//AuthorizationRules.AllowWrite("EventTitle", "EventDetailWriteGroup");
			//AuthorizationRules.AllowWrite("EventDetails", "EventDetailWriteGroup");
			//AuthorizationRules.AllowWrite("EventDateString", "EventDetailWriteGroup");
			//AuthorizationRules.AllowWrite("UserID", "EventDetailWriteGroup");
			//AuthorizationRules.AllowWrite("AllowSubscriptions", "EventDetailWriteGroup");
			//AuthorizationRules.AllowWrite("AllowComments", "EventDetailWriteGroup");
		}


		public static bool CanGetObject()
		{
			//TODO: Define CanGetObject permission in EventDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("EventDetailViewGroup"))
			//	return true;
			//return false;
		}

		public static bool CanAddObject()
		{
			//TODO: Define CanAddObject permission in EventDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("EventDetailAddGroup"))
			//	return true;
			//return false;
		}

		public static bool CanEditObject()
		{
			//TODO: Define CanEditObject permission in EventDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("EventDetailEditGroup"))
			//	return true;
			//return false;
		}

		public static bool CanDeleteObject()
		{
			//TODO: Define CanDeleteObject permission in EventDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("EventDetailDeleteGroup"))
			//	return true;
			//return false;
		}
		#endregion //Authorization Rules

		#region Factory Methods
		private EventDetail()
		{ /* require use of factory method */ }

		public static EventDetail NewEventDetail()
		{
			if (!CanAddObject())
				throw new System.Security.SecurityException("User not authorized to add a EventDetail");
			return DataPortal.Create<EventDetail>();
		}

		public static EventDetail GetEventDetail(Guid eventID)
		{
			if (!CanGetObject())
				throw new System.Security.SecurityException("User not authorized to view a EventDetail");
			return DataPortal.Fetch<EventDetail>(new Criteria(eventID));
		}

		public static void DeleteEventDetail(Guid eventID)
		{
			if (!CanDeleteObject())
				throw new System.Security.SecurityException("User not authorized to remove a EventDetail");
			DataPortal.Delete(new Criteria(eventID));
		}

        public static void DeleteEventDetail(Guid OccurenceID, Boolean DeleteRecurring)
        {
            if (!CanDeleteObject())
                throw new System.Security.SecurityException("User not authorized to remove a EventDetail");
            DataPortal.Delete(new Criteria(OccurenceID, DeleteRecurring));
        }

		public override EventDetail Save()
		{
			if (IsDeleted && !CanDeleteObject())
				throw new System.Security.SecurityException("User not authorized to remove a EventDetail");
			else if (IsNew && !CanAddObject())
				throw new System.Security.SecurityException("User not authorized to add a EventDetail");
			else if (!CanEditObject())
				throw new System.Security.SecurityException("User not authorized to update a EventDetail");

			return base.Save();
		}

		#endregion //Factory Methods

		#region Data Access

		#region Criteria

		[Serializable()]
		private class Criteria
		{
			public Guid ItemID;
            public Boolean DeleteRecurring;

            public Criteria(Guid ItemID)
			{
                this.ItemID = ItemID;
			}

            public Criteria(Guid ItemID, Boolean DeleteRecurring)
            {
                this.ItemID = ItemID;
                this.DeleteRecurring = DeleteRecurring;
            }
		}

		#endregion //Criteria

		#region Data Access - Create
		[RunLocal]
		protected override void DataPortal_Create()
		{
			ValidationRules.CheckRules();
		}

		#endregion //Data Access - Create

		#region Data Access - Fetch
        private void DataPortal_Fetch(Criteria criteria)
        {
            ExecuteFetch(criteria);
        }

        private void ExecuteFetch(Criteria criteria)
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            DAL.AddParameter("@EventID", criteria.ItemID);

            using(SafeDataReader dr = new SafeDataReader(DAL.ExecuteReader(Procs.GetEventByEventID.ToString().Trim(), CommandType.Text, ConnectionState.Open)))
            {
                FetchObject(dr);
                ValidationRules.CheckRules();

                //load child object(s)
                FetchChildren(dr);
            }
        }

		private void FetchObject(SafeDataReader dr)
		{
			dr.Read();
            _eventID = dr.GetGuid("EventID");
            _eventTitle = dr.GetString("EventTitle");
            _eventDetails = dr.GetString("EventDetails");
            _eventDate = dr.GetSmartDate("EventDate", _eventDate.EmptyIsMin);
            _userID = dr.GetGuid("UserID");
            _startDate = dr.GetSmartDate("StartDate", _startDate.EmptyIsMin);
            _endDate = dr.GetSmartDate("EndDate", _endDate.EmptyIsMin);
            _day = dr.GetInt32("Day");
            _month = dr.GetInt32("Month");
            _year = dr.GetInt32("Year");
            _hr = dr.GetInt32("Hr");
            _min = dr.GetInt32("Min");
            _meridian = dr.GetString("Meridian");
            _occurenceid = dr.GetGuid("Occurenceid");
            _private = dr.GetBoolean("Private");
		}

		private void FetchChildren(SafeDataReader dr)
		{
		}
		#endregion //Data Access - Fetch

		#region Data Access - Insert
        protected override void DataPortal_Insert()
        {
            ExecuteInsert();
        }

        private void ExecuteInsert()
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddInsertParameters(ref DAL);

            DAL.ExecuteNonQuery(Procs.InsertEvent.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void AddInsertParameters(ref BA.DAL.DBUtility DAL)
        {
            DAL.AddParameter("@EventID", _eventID);
            DAL.AddParameter("@EventTitle", _eventTitle);
            DAL.AddParameter("@EventDetails", _eventDetails);
            DAL.AddParameter("@EventDate", _eventDate.DBValue);
            DAL.AddParameter("@UserID", _userID);
            DAL.AddParameter("@StartDate", _startDate.DBValue);
            DAL.AddParameter("@EndDate", _endDate.DBValue);
            if (_day != 0)
                DAL.AddParameter("@Day", _day);
            else
                DAL.AddParameter("@Day", DBNull.Value);
            if (_month != 0)
                DAL.AddParameter("@Month", _month);
            else
                DAL.AddParameter("@Month", DBNull.Value);
            if (_year != 0)
                DAL.AddParameter("@Year", _year);
            else
                DAL.AddParameter("@Year", DBNull.Value);
            if (_hr != 0)
                DAL.AddParameter("@Hr", _hr);
            else
                DAL.AddParameter("@Hr", DBNull.Value);
            if (_min != 0)
                DAL.AddParameter("@Min", _min);
            else
                DAL.AddParameter("@Min", DBNull.Value);
            if (_meridian.Length > 0)
                DAL.AddParameter("@Meridian", _meridian);
            else
                DAL.AddParameter("@Meridian", DBNull.Value);
            if (_occurenceid != Guid.Empty)
                DAL.AddParameter("@Occurenceid", _occurenceid);
            else
                DAL.AddParameter("@Occurenceid", DBNull.Value);
            if (_private != false)
                DAL.AddParameter("@Private", _private);
            else
                DAL.AddParameter("@Private", DBNull.Value);
		}
		#endregion //Data Access - Insert

		#region Data Access - Update
        protected override void DataPortal_Update()
        {
            if (base.IsDirty)
            {
                ExecuteUpdate();
            }
        }

        private void ExecuteUpdate()
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddUpdateParameters(ref DAL);

            if (UpdateOccurence)
            {
                DAL.ExecuteNonQuery(Procs.UpdateEventByOccurenceID.ToString().Trim(), CommandType.Text, ConnectionState.Open);
            }
            else
            {
                DAL.ExecuteNonQuery(Procs.UpdateEvent.ToString().Trim(), CommandType.Text, ConnectionState.Open);
            }
        }

        private void AddUpdateParameters(ref BA.DAL.DBUtility DAL)
        {
            DAL.AddParameter("@EventID", _eventID);
            DAL.AddParameter("@EventTitle", _eventTitle);
            DAL.AddParameter("@EventDetails", _eventDetails);
            DAL.AddParameter("@EventDate", _eventDate.DBValue);
            DAL.AddParameter("@StartDate", _startDate.DBValue);
            DAL.AddParameter("@EndDate", _endDate.DBValue);
            if (_day != 0)
                DAL.AddParameter("@Day", _day);
            else
                DAL.AddParameter("@Day", DBNull.Value);
            if (_month != 0)
                DAL.AddParameter("@Month", _month);
            else
                DAL.AddParameter("@Month", DBNull.Value);
            if (_year != 0)
                DAL.AddParameter("@Year", _year);
            else
                DAL.AddParameter("@Year", DBNull.Value);
            if (_hr != 0)
                DAL.AddParameter("@Hr", _hr);
            else
                DAL.AddParameter("@Hr", DBNull.Value);
            if (_min != 0)
                DAL.AddParameter("@Min", _min);
            else
                DAL.AddParameter("@Min", DBNull.Value);
            if (_meridian.Length > 0)
                DAL.AddParameter("@Meridian", _meridian);
            else
                DAL.AddParameter("@Meridian", DBNull.Value);
            if (_occurenceid != Guid.Empty)
                DAL.AddParameter("@Occurenceid", _occurenceid);
            else
                DAL.AddParameter("@Occurenceid", DBNull.Value);
            if (_private != false)
                DAL.AddParameter("@Private", _private);
            else
                DAL.AddParameter("@Private", DBNull.Value);
		}

		private void UpdateChildren(SqlConnection cn)
		{
		}
		#endregion //Data Access - Update

		#region Data Access - Delete
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(new Criteria(_eventID));
        }

        private void DataPortal_Delete(Criteria criteria)
        {
            ExecuteDelete(criteria);
        }

        private void ExecuteDelete(Criteria criteria)
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            DAL.AddParameter("@EventID", criteria.ItemID);
            DAL.ExecuteNonQuery(Procs.DeleteEvent.ToString().Trim(), CommandType.Text, ConnectionState.Open);
            Procs.PurgeItemsByItemID(criteria.ItemID);
        }

		#endregion //Data Access - Delete
		#endregion //Data Access
	}
}
